package com.impinj.program;

import java.sql.SQLException;
import java.sql.Statement;

import com.impinj.octane.AntennaConfigGroup;
import com.impinj.octane.ImpinjReader;
import com.impinj.octane.OctaneSdkException;
import com.impinj.octane.Settings;
import com.impinj.octane.TagOpCompleteListener;
import com.impinj.octane.TagOpReport;
import com.impinj.octane.TagOpSequence;
import com.impinj.octane.TagReadOp;
import com.impinj.octane.TagReadOpResult;

public class Main20240426 {
	
	// 定义类级变量
	private static String hostname = null;
	
	// 获取程序运行时附带的参数
	private static String roomname = null;		// 获取程序运行的房间名
	private static int endTimes = 0;			// 获取程序运行结束的次数
	
	// 设置自动退出循环
	private static int totalTimesCountOfTwoTablesBigInteger = 0;		// 用于计算两个表格相等的总次数
	//private static int sameValuesBetweenTwoTables = 0;					// 用于储存两个表格中有多少相同的元素
	private static int closeTimeCnt = 0;

	
	// 主程序
	public static void main(String[] args) {
		if(args.length != 3){
			System.out.println("输入参数错误，正确方式为：java -jar *.jar 612B(房间) 30(扫描次数) 0或1(1表示清除旧扫描数据)");
			System.exit(0);
		}
		
		/* 获取初始化数据 */
		// 获取程序输入的第1个值，转化为运行房间
		roomname = args[0];
		// 尝试获取程序输入的第2个值，转化为运行结束的次数
		// 如果 endTimes 没有数值，则默认设置 5000
		endTimes = Integer.parseInt(args[1]);
		//(Integer.parseInt(args[1]) == 0) ? Integer.parseInt(args[1]) : 100;
		System.out.println("set room: "+args[0]);
		System.out.println("set read times: "+args[1]);
		
		// 新建 Assets Inventory 的数据库
		JDBCUtils.bulidAssetsInventory();
		
		// 初始化读写器
		ImpinjReader reader = new ImpinjReader();
		
		// 获取读写器地址
		// i为计数，在等待一段时间连接不上读写器后，将直接退出程序
		for (int i = 0; i < 10; i++) {
			// 读写器地址获取成功
			hostname = InitializeReader.getHostname();
			
			// 延时 3s
			InitializeReader.delay(3);
			
			// 判断 hostname 是不是空的
			if (!hostname.isEmpty()) {
				if (InitializeReader.connectToReader(reader, hostname)) {	//读写器连接成功
					System.out.println("》》》读写器初始化完成《《《");
					break;
				}
			} 
			
			// 当长时间无法连接读写器的时候，将退出程序
			if (i == 9) {
				System.out.println("请检查读写器的连接，程序将在三秒后退出");
				InitializeReader.delay(3);
				System.exit(0);
			}
		}
		System.out.println(hostname);
		
		// 连接数据库，创建数据库执行环境
		final Statement[] statement = { null };
		try {
		    statement[0] = JDBCUtils.createStatement();
			System.out.println("数据库环境创建成功");
		} catch (SQLException e) {
		    System.out.println("！！！数据库环境创建失败！！！");
		}
		
		// 创建一个临时表格
		JDBCUtils.isTableExist(statement[0], "tempTable");
		if(Integer.parseInt(args[2]) != 0){
			JDBCUtils.deleteData(statement[0], "task", "roomname", roomname);
		}
/*----------------------------------------------------------------------------------------------------------------*/			

		// 读写器进行读操作
				// 选择天线
				try {
					// 获取天线的默认配置
					Settings settings = reader.queryDefaultSettings();
					settings.getReport().setIncludeAntennaPortNumber(true);
			        // 关闭所有天线 
			        AntennaConfigGroup antennas = settings.getAntennas();
			        antennas.disableAll();
			        // 使能对应的天线，此处为1
			        antennas.enableById(new short[]{1});
					reader.applySettings(settings);
					System.out.println("完成默认配置");
					// 创建标签操作序列
					TagOpSequence seq = ReadMode.creatTagOpSequence();
					System.out.println("读写器操作序列创建成功");
					// 创建标签读序列
					TagReadOp readOp = ReadMode.creatTagReadOp();
					System.out.println("设置读 user 区成功");
					seq.getOps().add(readOp);
					// 配置读模式
					TagOpSequence seqConfig = ReadMode.configReadMode(reader, seq);
					reader.addOpSequence(seqConfig);
					System.out.println("配置读模式成功");
					
					// 读写模式
					// 自定义的显示模块，内容在 MyTagOpCompleteListernerImplementation 中
					MyTagOpCompleteListernerImplementation myTagOpCompleteListernerImplementation = 
							new MyTagOpCompleteListernerImplementation();
					reader.setTagOpCompleteListener(new TagOpCompleteListener() {
						@Override
						public void onTagOpComplete(ImpinjReader reader, TagOpReport results) {
							closeTimeCnt++;
							System.out.println("count down "+ String.valueOf(endTimes-closeTimeCnt));
							if (closeTimeCnt >= endTimes) {
								// 显示相应信息
								System.out.println("Stopping  " + hostname);
								// 尝试停止读写器
								try {
									reader.stop();
								} catch (OctaneSdkException e) {
									System.out.println("程序运行可能存在问题 : " + e);
								}
								
								// 断开与读写器的连接
								System.out.println("Disconnecting from " + hostname);
								reader.disconnect();
								
								try{
									// 对数据库进行去重
									JDBCUtils.removeDuplicatesInSql(statement[0], "task");
									
									// 丢弃数据库
									JDBCUtils.dropTableIfExists(statement[0], "tempTable");
								}
								catch(Exception ex){}
								
								System.out.println("Done");
								System.exit(0);
							}
							// 显示读取的标签
							TagReadOpResult tr = 
									myTagOpCompleteListernerImplementation.myOnTagOpComplete(
											reader, results);
							// 接下来这部分是排除掉无用标签的干扰，只写入对应房间的标签信息
							// 其中，roomName 是程序从标签中读到的房间号的信息；roomname 是程序运行时候附带的房间号信息
							// 这个if用于排除多余标签干扰

							String tagRoomname = tr.getData().toHexString().substring(0, 4);
							// 当读到的标签非全0，且与小车所在的房间相同时，运行以下程序
							if (!tagRoomname.equals("0000") && tagRoomname.equalsIgnoreCase(roomname)) {
								// 下面这个部分为自动退出程序的判断条件
								// 判断思路：当 roomName 的表格内容与 roomName_r 的表格内容相同的次数为 endTimes 次时，结束程序运行
								// 当两个表格差异数相同的时候，增加一次总计数
								
								
								// 检查表格是否有重复的数据
								// 对 tempTable，数据写入嵌入在 isTableExist 中
								boolean tagInTable = JDBCUtils.isTagInTable(statement[0], tr, "tempTable");
								
								if (tagInTable) {
									// 如果标签在表格当中，则总计数加一
									totalTimesCountOfTwoTablesBigInteger++;
									// 写入 tempTable 的语句在 isTagInTable 中
								}
								else {
									// 将数据写入 task 的表格中
									JDBCUtils.writeResult(statement[0], tr, "task");
									// 出现了没有出现过的表格，计数清 0
									totalTimesCountOfTwoTablesBigInteger = 0;
								}
								
							}

							
						}
					});
					reader.start();
				} catch (OctaneSdkException ex) {
		            System.out.println("Octane SDK exception : " + ex.getMessage());
		            try {
						reader.stop();
						reader.disconnect();
					} catch (OctaneSdkException e) {
						e.printStackTrace();
					}
		        } catch (Exception ex) {
		            System.out.println("Exception : " + ex.getMessage());
		            ex.printStackTrace(System.out);
		            try {
						reader.stop();
						reader.disconnect();
					} catch (OctaneSdkException e) {
						e.printStackTrace();
					}
		        } 
		
		
		
		}
	
	
}



